<template>
  <div>
    <ul>
      <li @mouseenter="show(index)" @mouseleave="hide(index)" v-for='(item, index) in filterData' :key='item.key' @click.stop="handleClick(item)">
        <span  @click='expandNode(item.node)' class='di-tree' v-show='item.parent==undefined || item.parent.expanded==undefined || item.parent.expanded==true'>
          <span :style="{'padding-left': width*item.level+10+'px'}">
             <span v-if='multiple' :class="[item.checked ? (item.chkDisabled ? 'box-halfchecked' : 'box-checked') : 'box-unchecked', 'inputCheck']">
                  <input :disabled="item.chkDisabled" :class="['check', item.chkDisabled ? 'chkDisabled' : '']" v-if='multiple' type="checkbox" @change="changeNodeCheck(item, $event)" v-model="item.checked"/>
              </span>
            {{ item.node.title }}
          </span>
          <span v-if="index == showIndex">
          <render :node="item" :tpl="tpl"></render>
          </span>
        </span>
      </li>
    </ul>
  </div>
</template>
<script>
  import Render from './render'
  var ergodic = function (val, array1, level, parent) {
    for (let i = 0; i < val.length; i++) {
      array1.push({ node: val[i], level: level, parent: parent })
      if (val[i].children) {
        ergodic(val[i].children, array1, level + 1, val[i])
      }
    }
  }
  var pushNode = function (arr1, node, filterData) {
    // rgodic(items.parent, this.arrp, 0)
    if (node.parent !== undefined) {
      arr1.forEach(item => {
        if (item.node === node.parent) {
          if (filterData.indexOf(item) === -1) {
            pushNode(arr1, item, filterData)
            filterData.splice(filterData.length - 1, 0, item)
          }
        }
      })
    }
  }
  export default {
    props: {
      multiplecheck: Boolean, //  半选
      multiple: Boolean, //  复选
      tpl: Function,
      button: Boolean,
      data: Array,
      filterKey: String
    },
    data () {
      return {
        width: 18,
        arr1: [],
        arrp: [],
        buttonlist: false,
        showIndex: -1
      }
    },
    mounted () {
      console.log(this.data, 'tttt')
      ergodic(this.data, this.arr1, 0)
      //  子级复选框选中
      this.$on('childchecked', (node, checked) => {
        this.$set(node, 'expanded', true)
        if (node.children && node.children.length) {
          for (let child of node.children) {
            this.$set(child, 'checked', checked)
            this.$emit('nodeChecked', child, checked)
          }
        }
      })
      //  被选中的复选框
      this.$on('nodeChecked', (node, checked) => {
        console.log(this.scoped, 'w s b')
        if (!this.scoped) {
          console.log(node, 'node')
          console.log(checked, 'checked')
          this.$emit('parentChecked', node, checked)
          this.$emit('childChecked', node, checked)
        } else {
          this.$set(node.node, 'checked', checked)
        }
      })
      //  父级复选框选中
      this.$on('parentChecked', (node, checked) => {
        console.log('我被选中了', node.parent)
        this.$set(node, 'expanded', true)
        this.$set(node, 'checked', checked)
        if (!node.parent) return false
        let someBortherNodeChecked = node.parent.children.some(node => node.checked)
        let allBortherNodeChecked = node.parent.children.every(node => node.checked)
        if (this.multiplecheck) {
          allBortherNodeChecked ? this.$set(node.parent, 'multiplecheck', false) : someBortherNodeChecked ? this.$set(node.parent, 'halfcheck', true) : this.$set(node.parent, 'halfcheck', false)
          if (!checked && someBortherNodeChecked) {
            this.$set(node.parent, 'multiplecheck', true)
            return false
          }
          this.$emit('parentChecked', node.parent, checked)
        } else {
          if (checked && allBortherNodeChecked) this.$emit('parentChecked', node.parent, checked)
          if (!checked) this.$emit('parentChecked', node.parent, checked)
        }
      })
    },
    components: {Render},
    computed: {
      filterData () {
        const filterKey = this.filterKey && this.filterKey.toLowerCase()
        if (filterKey) {
          let filterData = []
          this.arr1.forEach(items => {
            items.node.expanded = true //  展开搜索
            console.log(items.node.title, 'title')
            var convert = require('convert-chinese-to-pinyin')
            console.log(convert(items.node.title), 'rer')
            if (items.node.title.includes(filterKey) || convert(items.node.title).toLowerCase().includes(filterKey)) {
              filterData.push(items)
              pushNode(this.arr1, items, filterData) // 三个参数 ，所有的节点，当前过滤通过的节点，过滤后的数组 从所有的节点中查找当前节点父节点然后插入到当前节点的前边
              console.log('过滤的节点所有对象', filterData[items.level])
            }
          })
          console.log(filterData, 'arr1')
          return filterData
        } else {
          console.log(this.arr1, 'arrr 1')
          return this.arr1
        }
      }
    },
    watch: {
      data (val) {
        console.log('he', this.data)
      },
      buttonlist (val) {
        console.log('r', this.buttonlist)
      },
      arr1 (val) {
        console.log(this.arr1, '数组发生改变了')
      },
      filterData (val) {
        console.log(this.arr1, '数组发生改变了')
      }
    },
    methods: {

      //  复选框被选中的事件
      changeNodeCheck: function (a, b) {
        console.log('fff', a)
        console.log('ccc', b)
        this.$emit('nodeChecked', a, b.target.checked)
      },
      addNodes (node, children) {
        console.log('hh', children)
        for (let n of children.children) {
          this.addNode(node, n)
        }
      },
     /*
     * 添加节点
     */
      addNode (parent, data) {
        console.log('rwerw', data)
        this.$set(data.node, 'expanded', false)
        const newChild = {title: 'xixi', children: []}
        data.node.children.push(newChild)
        this.$emit('addNode', {parent: parent, new: data})
      },
     /*
     * 删除节点
     */
      delNode (parent, node) {
        if (parent === null || typeof parent === 'undefined') {
          throw new ReferenceError('the root element can\'t deleted!')
        }
        parent.children.splice(parent.children.indexOf(node), 1)
        console.log('删除node', parent)
        this.$emit('delNode', { parentNode: parent, delNode: node })
      },
      show: function (node) {
        this.showIndex = node
      },
      hide: function (node) {
        this.showIndex = -1
      },
      initTree () {
        for (let node of this.data) {
          this.$set(node, 'parent', this.parent)
        }
      },
      //  节点点击事件
      handleClick (item) {
        this.$emit('node-click', item.node)
      },
      isLeaf (node) {
        console.log(node, 'node')
        return !(node.children && node.children.length) && node.parent
//        console.log(this.parent, 'parent')
//        console.log(node.children + node.parent + node.children, 'rwerw')
//        return !node.children && node.parent
      },
      //  关闭打开节点
      expandNode (node, expanded) {
        if (expanded === undefined) {
          this.$set(node, 'expanded', !node.expanded)
        } else { this.$set(node, 'expanded', expanded) }
        if (node.children) {
          for (let i = 0; i < node.children.length; i++) {
            this.expandNode(node.children[i], node.expanded)
          }
        }
      }
    }
  }
</script>
<style>
  input[type="checkbox"]
  {
    margin:0
  }
  ul li {
    list-style: none;
  }
  .di-tree {
    flex: 1 1 0%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
    height: 26px;
    cursor: pointer;
  }
  .di-tree:hover {
    background-color: #f5f7fa
  }
  .di-button{
    border-color: transparent;
    color: #409eff;
    background: transparent;
    padding-left: 0;
    padding-right: 0;
  }
  .check{
    opacity: 0;
  }
  .box-halfchecked{
    border:1px solid #dcdfe6;
    border-radius: 2px;
    width: 14px;
    height: 14px;
    z-index: 1;
    white-space: nowrap;
    cursor: pointer;
    outline: none;
    display: inline-block;
    line-height: 1;
    position: relative;
    vertical-align: middle;
  }
  .box-halfchecked:after{
    content: "";
    position: absolute;
    display: block;
    background-color: #9398a0;
    height: 2px;
    transform: scale(.5);
    left: 0;
    right: 0;
    top: 5px;
  }
  .box-checked{
    border:1px solid #dcdfe6;
    border-radius: 2px;
    width: 14px;
    height: 14px;
    z-index: 1;
    white-space: nowrap;
    cursor: pointer;
    outline: none;
    display: inline-block;
    line-height: 1;
    position: relative;
    vertical-align: middle;
  }
  .box-checked:after{
    z-index: 1;
    cursor: pointer;
    box-sizing: content-box;
    content: "";
    border:2px solid #9398a0;
    height:7px;
    width:4px;
    left:4px;
    top:1px;
    border-top:0;
    border-left:0;
    position:absolute;
    transform: rotate(45deg) scaleY(1);
    transition:transform .15s cubic-bezier(.71,-.46,.88,.6) .05s;
    transition-property: transform;
    transition-duration: 0.15s;
    transition-timing-function: cubic-bezier(0.71, -0.46, 0.88, 0.6);
    transition-delay: 0.05s;
    transform-origin: center;
  }
  .box-unchecked{
    border:1px solid #dcdfe6;
    border-radius: 2px;
    width: 14px;
    height: 14px;
    z-index: 1;
    white-space: nowrap;
    outline: none;
    display: inline-block;
    line-height: 1;
    position: relative;
    vertical-align: middle;
  }
</style>
